﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EntityFramework.Extensions;
using System.Threading.Tasks;
using System.Threading;
using System.Data.SqlClient;
using System.Data;
using XLugia.Lib.XDataBase.Base.Lib;
using XLugia.Lib.XDataBase.Base.Model;

namespace XLugia.Lib.XDataBase.Engine.MySQL.Lib
{
    /// <summary>
    /// 数据库脚本执行控制器
    /// </summary>
    public class MySQLExecutor : DatabaseExecutor
    {
        /// <summary>
        /// 数据库脚本执行控制器
        /// </summary>
        /// <param name="databaseConnector">数据库连接器。</param>
        public MySQLExecutor(DatabaseConnector databaseConnector)
            : base(new DatabaseConnector()
            {
                connectionString = databaseConnector.connectionString,
                commandTimeout = databaseConnector.commandTimeout,
                databaseType = databaseConnector.databaseType,
                isolationLevel = databaseConnector.isolationLevel,
                metadata = "metadata=res://*/Metadata.DatabaseModel.csdl|res://*/Metadata.DatabaseModel.ssdl|res://*/Metadata.DatabaseModel.msl;provider=MySql.Data.MySqlClient;provider connection string=\"" + databaseConnector.connectionString + "\""
            })
        {
        }

        #region MySQL大批量高速数据插入
        /// <summary>
        /// 将DataTable中的数据大批量高速写入至数据库，目前只支持字符、数字、时间、布尔类型。
        /// </summary>
        /// <param name="sqlDataTable">DataTable数据源</param>
        public void executeMySQLBulkSqlCommand(DataTable sqlDataTable)
        {
            try
            {
                int rowIndex = 0;
                int columnIndex = 0;
                DatabaseScriptModel scriptModel = new DatabaseScriptModel();
                StringBuilder sb = new StringBuilder();
                sb.Append("INSERT INTO `" + sqlDataTable.TableName.Replace("`", "``") + "`" );

                //生成字段
                sb.Append("(");
                columnIndex = 0;
                foreach (DataColumn dc in sqlDataTable.Columns)
                {
                    sb.Append((columnIndex > 0 ? "," : ""));
                    sb.Append("`" + dc.ColumnName.Replace("`", "``") + "`");
                    columnIndex++;
                }
                sb.Append(")");

                //填充Values
                sb.Append(" VALUES ");
                foreach (DataRow dr in sqlDataTable.Rows)
                {
                    columnIndex = 0;
                    sb.Append((rowIndex > 0 ? "\r\n," : "" ) + "(");
                    foreach (DataColumn dc in sqlDataTable.Columns)
                    {
                        //NULL的时候
                        if (dr[dc.ColumnName] == null)
                        {
                            sb.Append((columnIndex > 0 ? "," : "") + "NULL");
                            columnIndex++;
                            continue;
                        }

                        //非NULL时，根据数据类型填充
                        sb.Append((columnIndex > 0 ? "," : ""));
                        switch (dc.DataType.Name.ToLower())
                        {
                            case "bool":
                            case "boolean":
                                sb.Append(dr[dc.ColumnName].ToString());
                                break;
                            default:
                                sb.Append("'" + dr[dc.ColumnName].ToString().Replace("'", "''") + "'");
                                break;
                        }
                        columnIndex++;
                    }
                    sb.Append(")");
                    rowIndex++;
                }
                sb.Append(";");
                scriptModel.command = sb.ToString();

                base.executeSqlCommand(new List<DatabaseScriptModel> { scriptModel });
            }
            catch (Exception ex)
            {
                throw DatabaseException.getSqlException("executeMySQLBulkSqlCommand", sqlDataTable, ex);
            }
        }
        #endregion
    }
}
